﻿#region imports

using System;
using System.Data.Services;
using System.Globalization;
using System.Linq;
using Codeplex.ODataTFS.Model.Entities;
using Codeplex.ODataTFS.Model.Repositories;
using Codeplex.ODataTFS.Model.Serialization;
using Microsoft.Data.Services.Toolkit.QueryModel;
using Microsoft.TeamFoundation;

#endregion

namespace Codeplex.ODataTFS.Model
{
	public class TFSDataContext : ODataContext
	{
		private readonly TFSProxyFactory _tfsProxyFactory;

		public TFSDataContext(TFSProxyFactory tfsProxyFactory)
		{
			_tfsProxyFactory = tfsProxyFactory;
		}

		public IQueryable<Build> Builds
		{
			get { return CreateQuery<Build>(); }
		}

		public IQueryable<BuildDefinition> BuildDefinitions
		{
			get { return CreateQuery<BuildDefinition>(); }
		}

		public IQueryable<Changeset> Changesets
		{
			get { return CreateQuery<Changeset>(); }
		}

		public IQueryable<Project> Projects
		{
			get { return CreateQuery<Project>(); }
		}

		public IQueryable<WorkItem> WorkItems
		{
			get { return CreateQuery<WorkItem>(); }
		}

		public IQueryable<Attachment> Attachments
		{
			get { return CreateQuery<Attachment>(); }
		}

		public IQueryable<Change> Changes
		{
			get { return CreateQuery<Change>(); }
		}

		public IQueryable<Query> Queries
		{
			get { return CreateQuery<Query>(); }
		}

		public IQueryable<Branch> Branches
		{
			get { return CreateQuery<Branch>(); }
		}

		public IQueryable<AreaPath> AreaPaths
		{
			get { return CreateQuery<AreaPath>(); }
		}

		public IQueryable<Link> Links
		{
			get { return CreateQuery<Link>(); }
		}

		public IQueryable<IterationPath> IterationPaths
		{
			get { return CreateQuery<IterationPath>(); }
		}

		public IQueryable<User> Users
		{
			get { return CreateQuery<User>(); }
		}

		public void TriggerBuild(string project, string definition)
		{
			var proxy = _tfsProxyFactory.TfsBuildDefinitionProxy;

			proxy.QueueBuild(project, definition);
		}

		public override object RepositoryFor(string fullTypeName)
		{
			try
			{
				if (fullTypeName == typeof (Build).FullName || fullTypeName == typeof (Build[]).FullName)
				{
					return new BuildRepository(_tfsProxyFactory.TfsBuildProxy);
				}

				if (fullTypeName == typeof (BuildDefinition).FullName || fullTypeName == typeof (BuildDefinition[]).FullName)
				{
					return new BuildDefinitionRepository(_tfsProxyFactory.TfsBuildDefinitionProxy);
				}

				if (fullTypeName == typeof (Changeset).FullName || fullTypeName == typeof (Changeset[]).FullName)
				{
					return new ChangesetRepository(_tfsProxyFactory.TfsChangesetProxy);
				}

				if (fullTypeName == typeof (Project).FullName || fullTypeName == typeof (Project[]).FullName)
				{
					return new ProjectRepository(_tfsProxyFactory.TfsProjectProxy);
				}

				if (fullTypeName == typeof (Change).FullName || fullTypeName == typeof (Change[]).FullName)
				{
					return new ChangeRepository(_tfsProxyFactory.TfsChangeProxy);
				}

				if (fullTypeName == typeof (WorkItem).FullName || fullTypeName == typeof (WorkItem[]).FullName)
				{
					return new WorkItemRepository(_tfsProxyFactory.TfsWorkItemProxy);
				}

				if (fullTypeName == typeof (Attachment).FullName || fullTypeName == typeof (Attachment[]).FullName)
				{
					return new AttachmentRepository(_tfsProxyFactory.TfsAttachmentProxy);
				}

				if (fullTypeName == typeof (Query).FullName || fullTypeName == typeof (Query[]).FullName)
				{
					return new QueryRepository(_tfsProxyFactory.TfsQueryProxy);
				}

				if (fullTypeName == typeof (Branch).FullName || fullTypeName == typeof (Branch[]).FullName)
				{
					return new BranchRepository(_tfsProxyFactory.TfsBranchProxy);
				}

				if (fullTypeName == typeof (AreaPath).FullName || fullTypeName == typeof (AreaPath[]).FullName)
				{
					return new AreaPathRepository(_tfsProxyFactory.TfsAreaPathProxy);
				}

				if (fullTypeName == typeof (Link).FullName || fullTypeName == typeof (Link[]).FullName)
				{
					return new LinkRepository(_tfsProxyFactory.TfsLinkProxy);
				}

				if (fullTypeName == typeof (IterationPath).FullName || fullTypeName == typeof (IterationPath[]).FullName)
				{
					return new IterationPathRepository(_tfsProxyFactory.TfsIterationPathProxy);
				}

				if (fullTypeName == typeof (User).FullName || fullTypeName == typeof (User[]).FullName)
				{
					return new UserRepository(_tfsProxyFactory.TfsUserProxy);
				}

				throw new NotSupportedException(string.Format(CultureInfo.InvariantCulture, "The type '{0}' does not have its corresponding repository", fullTypeName));
			}
			catch (TeamFoundationServerUnauthorizedException ex)
			{
				throw new DataServiceException(403, "Forbidden", "Could not connect to the TFS Server. Make sure you are including the appropriate credentials in the HTTP headers for Basic Authentication.", "en-US", ex);
			}
		}
	}
}
